<!doctype html>



  


<html class="theme-next muse use-motion">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />












  
  
  <link href="/vendors/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/vendors/font-awesome/css/font-awesome.min.css?v=4.4.0" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.0.1" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="consul,spring boot," />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.0.1" />






<meta name="description" content="标签（空格分隔）： consul



Consul简介
安装及运行
K/V存储
Java案例（基于Spring boot）
ACL配置
小结">
<meta property="og:type" content="article">
<meta property="og:title" content="consul 配置---K/V存储及ACL">
<meta property="og:url" content="http://yoursite.com/2016/08/28/consul-config/index.html">
<meta property="og:site_name" content="个人博客">
<meta property="og:description" content="标签（空格分隔）： consul



Consul简介
安装及运行
K/V存储
Java案例（基于Spring boot）
ACL配置
小结">
<meta property="og:image" content="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/kv.jpg">
<meta property="og:image" content="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/kvex.jpg">
<meta property="og:image" content="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/ac.jpg">
<meta property="og:image" content="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/403.jpg">
<meta property="og:updated_time" content="2017-01-19T07:14:12.692Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="consul 配置---K/V存储及ACL">
<meta name="twitter:description" content="标签（空格分隔）： consul



Consul简介
安装及运行
K/V存储
Java案例（基于Spring boot）
ACL配置
小结">
<meta name="twitter:image" content="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/kv.jpg">



<script type="text/javascript" id="hexo.configuration">
  var NexT = window.NexT || {};
  var CONFIG = {
    scheme: 'Muse',
    sidebar: {"position":"left","display":"post"},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: 0,
      author: '博主'
    }
  };
</script>




  <link rel="canonical" href="http://yoursite.com/2016/08/28/consul-config/"/>

  <title> consul 配置---K/V存储及ACL | 个人博客 </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  










  
  
    
  

  <div class="container one-collumn sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-meta ">
  

  <div class="custom-logo-site-title">
    <a href="/"  class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <span class="site-title">个人博客</span>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>
  <p class="site-subtitle">随便写点什么</p>
</div>

<div class="site-nav-toggle">
  <button>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
    <span class="btn-bar"></span>
  </button>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      

      
    </ul>
  

  
</nav>

 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  
  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                consul 配置---K/V存储及ACL
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            <span class="post-meta-item-icon">
              <i class="fa fa-calendar-o"></i>
            </span>
            <span class="post-meta-item-text">发表于</span>
            <time itemprop="dateCreated" datetime="2016-08-28T14:55:33+08:00" content="2016-08-28">
              2016-08-28
            </time>
          </span>

          
            <span class="post-category" >
              &nbsp; | &nbsp;
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
              
                <span itemprop="about" itemscope itemtype="https://schema.org/Thing">
                  <a href="/categories/consul/" itemprop="url" rel="index">
                    <span itemprop="name">consul</span>
                  </a>
                </span>

                
                

              
            </span>
          

          
            
              <span class="post-comments-count">
                &nbsp; | &nbsp;
                <a href="/2016/08/28/consul-config/#comments" itemprop="discussionUrl">
                  <span class="post-comments-count ds-thread-count" data-thread-key="2016/08/28/consul-config/" itemprop="commentsCount"></span>
                </a>
              </span>
            
          

          

          
          

          
        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>标签（空格分隔）： consul</p>
<hr>
<blockquote>
<ul>
<li>Consul简介</li>
<li>安装及运行</li>
<li>K/V存储</li>
<li>Java案例（基于Spring boot）</li>
<li>ACL配置</li>
<li>小结</li>
</ul>
</blockquote>
<hr>
<a id="more"></a>
<h3 id="1-Consul简介"><a href="#1-Consul简介" class="headerlink" title="1.Consul简介"></a>1.Consul简介</h3><h4 id="1-1-consul的作用"><a href="#1-1-consul的作用" class="headerlink" title="1.1 consul的作用"></a>1.1 consul的作用</h4><ul>
<li>服务发现<ul>
<li>Consul clients提供服务（例如API）</li>
<li>其他的client发现服务的提供者（通过DNS或http，应用可以轻松的发现他们所依赖的服务）</li>
</ul>
</li>
<li>健康检查</li>
<li>Key-Value存储操作<ul>
<li>动态配置</li>
<li>leader选举</li>
<li>feature flagging</li>
<li>coordination</li>
</ul>
</li>
<li>多数据中心（DC）  <ul>
<li>用于容灾</li>
</ul>
</li>
</ul>
<h4 id="1-2-consul的基本架构"><a href="#1-2-consul的基本架构" class="headerlink" title="1.2 consul的基本架构"></a>1.2 consul的基本架构</h4><ul>
<li>一个consul节点对应一个consul agent<ul>
<li>agent会负责节点的健康检查和节点上的服务的健康检查</li>
</ul>
</li>
<li>agent分为server和client<ul>
<li>server<ul>
<li>存储数据</li>
<li>复制数据</li>
<li>servers们自己选择一个leader</li>
<li>每个数据中心推荐有3或5个server（官方推荐，但是只用单节点做server也是可以的，只是可能会数据丢失，两个节点的话，一个挂了，还是无法选举出leader，所以推荐3-5个）</li>
</ul>
</li>
<li>client<ul>
<li>个人感觉client只是作为一个与server交互的agent而已</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h3 id="2-安装及运行"><a href="#2-安装及运行" class="headerlink" title="2.安装及运行"></a>2.安装及运行</h3><h4 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h4><ul>
<li>OSX系统 ： 1. 如果安装了homebrew，直接 brew install consul进行安装， 如果没有，从<a href="https://www.consul.io/downloads.html选择合适的down下来之后解压安装" target="_blank" rel="external">https://www.consul.io/downloads.html选择合适的down下来之后解压安装</a></li>
<li>Linux系统：从<a href="https://www.consul.io/downloads.html上down下来，" target="_blank" rel="external">https://www.consul.io/downloads.html上down下来，</a> unzip解压， scp consul /usr/local/bin   再输入consul，如出现提示信息，则说明安装成功</li>
</ul>
<h4 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h4><ul>
<li><p>以server模式启动</p>
<ul>
<li>consul agent -server -bootstrap-expect 3 -data-dir /tmp/consul -node=service-center -bind=127.0.0.1 -client 0.0.0.0 -ui -config-dir ~/.consul_config/</li>
</ul>
</li>
<li><p>以client模式启动节点（非server都是client）</p>
<ul>
<li>consul agent -data-dir /tmp/consul -node=qianweifeng-mac -bind=192.168.15.16 -join 192.168.15.19</li>
</ul>
</li>
<li><p>集群模式</p>
<ul>
<li>consul的集群搭建相对容易，一般需要用3-5个server节点来搭建一个集群，启动方式就想上面说的server启动方式一致，就是在加上 -join ip地址 即可。至于3-5个节点，之前也说过，官方推荐，确实根据consul的leader推举机制来说，最少需要3个节点。</li>
<li>举个小例子：<br>现有节点A,B ，我们需要组建集群，那么自然是start A， start B， A join B （反过来也一样），如此，A,B就相互认识了。<br>此时有一个节点C要加入集群，我们不需要 C join A， C join B， 只需要选择A,B中的一个进行join就可以了。<br>其中的原理是给予gossip协议完成的</li>
</ul>
</li>
</ul>
<p>####关键指令介绍<br>agent 相当于是一个客户端，我觉得consul是没有意义明确的客户端与服务端的，只是节点启动的模式不同，而不是由运行于该节点之上的程序所决定的，所以agent相当于是一个客户端代理，通过它我们可以与consul集群进行交流。</p>
<p>-server 以server模式启动节点，相对的还要-client， 不过如果不指定-server，默认就是-client</p>
<p>-bootstrap-expect 3 这个东西是告诉consul集群，我们预计有3个server节点，该参数是为了延迟日志复制的启动直到我们指定数量的server节点成功的加入后启动。</p>
<p>-data-dir 指定agent储存状态的数据目录，比较重要</p>
<p>-config-dir 指定一个要装载的配置文件，可以是一个文件，也可以是一个目录下的所有文件，文件以.json后缀</p>
<p>-node 该节点在集群中的名称，具有唯一性，推荐直接用机器ip，便于区分辨别</p>
<p>-bind 说明该agent绑定的地址，通常情况是绑定本机</p>
<p>-join 加入集群</p>
<p>-rejoin 效果同上不过是在退出集群后再加入进去用的</p>
<p>特别注意：<br>-client 0.0.0.0 -ui 这个东西是为了能远程访问WEB UI界面，高版本的consul在远程访问WEB UI界面上似乎有些问题，也可能是我哪里没有配置好，所以访问不了。<br>使用这个指令后就可以远程访问了（目测这个指令的意思是，允许任何IP的客户端来访问WEB UI）</p>
<h3 id="3-K-V存储"><a href="#3-K-V存储" class="headerlink" title="3.K/V存储"></a>3.K/V存储</h3><p>关于K/V的作用在上一节已经说明了，这里来讲讲其具体应用。<br><img src="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/kv.jpg" alt="k/v"></p>
<p><img src="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/kvex.jpg" alt="kv-ex"></p>
<p>这个东西的话用来做动态配置比较多，比如我们有一些数据库配置，如果配置在本地，那么每次启动服务时还需要注意这些配置启动的正不正确，上传到测试环境时，也需要修改这些配置。但是如果我们用了K/V，我们要做的只是从不同的K/V拉去配置，而不需要修改代码。更重要的是，有一些非启动阶段读取的配置（也就是用到在读取的配置），可以做到动态更改，而不需要重启程序。</p>
<hr>
<h3 id="4-Java案例（基于Spring-boot）"><a href="#4-Java案例（基于Spring-boot）" class="headerlink" title="4.Java案例（基于Spring boot）"></a>4.Java案例（基于Spring boot）</h3><p>这里就动态配置，给出一个基于Spring Boot的具体案例</p>
<h4 id="1-maven依赖"><a href="#1-maven依赖" class="headerlink" title="1.maven依赖"></a>1.maven依赖</h4><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div></pre></td><td class="code"><pre><div class="line"><span class="comment">&lt;!--consul--&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.orbitz.consul<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>consul-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>0.10.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div><div class="line">        <span class="comment">&lt;!-- consul需要的包 --&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.glassfish.jersey.core<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>jersey-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>2.22.2<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div><div class="line">         <span class="comment">&lt;!-- 动态配置的实现 --&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework.boot<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-boot-starter-actuator<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div><div class="line">        <span class="comment">&lt;!-- archaius --&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.netflix.archaius<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>archaius-core<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>0.6.6<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div><div class="line">        <span class="comment">&lt;!-- 动态配置，archaius底层 --&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>commons-configuration<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>commons-configuration<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div><div class="line">         <span class="comment">&lt;!-- 这个只是一个比较easy的consul client api，与第一个选一个用即可 --&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.github.dcshock<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>consul-rest-client<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>0.7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line">        <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> com.config.center.config;</div><div class="line"></div><div class="line"><span class="keyword">import</span> com.config.center.common.CommonConstants;</div><div class="line"><span class="keyword">import</span> com.config.center.consul.ConsulInfo;</div><div class="line"><span class="keyword">import</span> com.config.center.consul.ConsulPropertySource;</div><div class="line"><span class="keyword">import</span> com.orbitz.consul.AgentClient;</div><div class="line"><span class="keyword">import</span> com.orbitz.consul.Consul;</div><div class="line"><span class="keyword">import</span> com.orbitz.consul.NotRegisteredException;</div><div class="line"><span class="keyword">import</span> consul.ConsulException;</div><div class="line"><span class="keyword">import</span> org.apache.commons.lang3.StringUtils;</div><div class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</div><div class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</div><div class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</div><div class="line"><span class="keyword">import</span> org.springframework.context.support.PropertySourcesPlaceholderConfigurer;</div><div class="line"><span class="keyword">import</span> org.springframework.core.env.ConfigurableEnvironment;</div><div class="line"></div><div class="line"><span class="keyword">import</span> javax.annotation.PostConstruct;</div><div class="line"><span class="keyword">import</span> java.io.IOException;</div><div class="line"><span class="keyword">import</span> java.net.URI;</div><div class="line"></div><div class="line"><span class="comment">/**</span></div><div class="line"> *</div><div class="line"> * <span class="doctag">@author</span> qwf</div><div class="line"> * <span class="doctag">@version</span> 2015-08-17</div><div class="line"> */</div><div class="line"><span class="meta">@Configuration</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConsulConfig</span> </span>&#123;</div><div class="line">    <span class="meta">@Autowired</span></div><div class="line">    <span class="keyword">private</span> ConfigurableEnvironment env;</div><div class="line"></div><div class="line">    <span class="meta">@PostConstruct</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">init</span><span class="params">()</span> <span class="keyword">throws</span> ConsulException, IOException, NotRegisteredException </span>&#123;</div><div class="line">        ConsulInfo info = getConsulInfo();</div><div class="line">        <span class="keyword">if</span> (info != <span class="keyword">null</span>) &#123;</div><div class="line">            env.getPropertySources().addFirst(<span class="keyword">new</span> ConsulPropertySource(<span class="string">"consul"</span>, info));</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="comment">/***</span></div><div class="line">     * 注册服务+健康检查</div><div class="line">     * 这里用了两种不同的consul client</div><div class="line">     * 因为一种对于KeyClient的处理相对方便,但是对于check的注册支持却不行,只能支持script检查</div><div class="line">     * 另一种对于KeyClient的处理相对麻烦,但是对于注册以及check的定义相对方便</div><div class="line">     * <span class="doctag">@return</span></div><div class="line">     * <span class="doctag">@throws</span> ConsulException</div><div class="line">     * <span class="doctag">@throws</span> IOException</div><div class="line">     * <span class="doctag">@throws</span> NotRegisteredException</div><div class="line">     */</div><div class="line">    <span class="function"><span class="keyword">public</span> ConsulInfo <span class="title">getConsulInfo</span><span class="params">()</span> <span class="keyword">throws</span> ConsulException, IOException, NotRegisteredException </span>&#123;</div><div class="line">        <span class="comment">//tag 来自于启动参数 -Dservice.tag=dev</span></div><div class="line">        String tag = env.getProperty(CommonConstants.CONSUL_TAG);</div><div class="line">        <span class="keyword">if</span> (StringUtils.isBlank(tag)) &#123;</div><div class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">"not specified "</span> + CommonConstants.CONSUL_TAG);</div><div class="line">        &#125;</div><div class="line"></div><div class="line">        <span class="keyword">if</span> (<span class="string">"local"</span>.equals(tag)) &#123;</div><div class="line">            <span class="keyword">return</span> <span class="keyword">null</span>;</div><div class="line">        &#125;</div><div class="line">        String service = CommonConstants.CONSUL_SERVICE_NAME;</div><div class="line">        Consul consul = Consul.builder().build();            <span class="comment">//建立consul实例</span></div><div class="line">        AgentClient agentClient = consul.agentClient();</div><div class="line">        agentClient.register(<span class="number">8800</span>, URI.create(<span class="string">"http://localhost:8800/health"</span>).toURL(), <span class="number">3</span>, service, <span class="string">"config-center"</span>, tag);</div><div class="line"><span class="comment">//        consul.agent().register(new ServiceProvider("config-center",</span></div><div class="line"><span class="comment">//                service, 8800,</span></div><div class="line"><span class="comment">//                new String[]&#123;tag&#125;));</span></div><div class="line"><span class="comment">//        consul.agent().checkRegister(new AgentCheck("id", service, "", "http://localhost:8800/health", "10s", "15s"));</span></div><div class="line"><span class="comment">//        Consul consul = new Consul("http://localhost", 8500);</span></div><div class="line"><span class="comment">//        KeyValue keyValue = new KeyValue(consul);</span></div><div class="line">        String keyName = String.format(<span class="string">"service/%s/%s/config"</span>, service, tag);</div><div class="line"></div><div class="line">        <span class="keyword">return</span> <span class="keyword">new</span> ConsulInfo(keyName, <span class="keyword">null</span>);</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="comment">/**</span></div><div class="line">     * IMPORTANT:</div><div class="line">     * 保证consul配置获取第一个被加载，防止spring启动的时候从本地加载配置</div><div class="line">     * 后期添加配置，如果依赖environment，也需要denpendsOn这个</div><div class="line">     */</div><div class="line">    <span class="meta">@Bean</span></div><div class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">trick</span><span class="params">()</span> </span>&#123;</div><div class="line">        System.out.println(<span class="string">"trick"</span>);</div><div class="line">        <span class="keyword">return</span> <span class="string">"trick"</span>;</div><div class="line">    &#125;</div><div class="line"></div><div class="line"></div><div class="line">    <span class="meta">@Bean</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> PropertySourcesPlaceholderConfigurer <span class="title">placeHolderConfigurer</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">return</span> <span class="keyword">new</span> PropertySourcesPlaceholderConfigurer();</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> com.config.center.consul;</div><div class="line"></div><div class="line"><span class="keyword">import</span> com.netflix.config.PollResult;</div><div class="line"><span class="keyword">import</span> com.netflix.config.PolledConfigurationSource;</div><div class="line"><span class="keyword">import</span> com.orbitz.consul.Consul;</div><div class="line"><span class="keyword">import</span> com.orbitz.consul.KeyValueClient;</div><div class="line"><span class="keyword">import</span> org.apache.http.util.TextUtils;</div><div class="line"><span class="keyword">import</span> org.slf4j.Logger;</div><div class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</div><div class="line"></div><div class="line"><span class="keyword">import</span> java.io.StringReader;</div><div class="line"><span class="keyword">import</span> java.util.HashMap;</div><div class="line"><span class="keyword">import</span> java.util.Map;</div><div class="line"><span class="keyword">import</span> java.util.Properties;</div><div class="line"></div><div class="line"><span class="comment">/**</span></div><div class="line"> * ConsulConfigurationSource</div><div class="line"> *</div><div class="line"> * <span class="doctag">@author</span> qwf</div><div class="line"> * <span class="doctag">@version</span> 2016-08-17</div><div class="line"> */</div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConsulConfigurationSource</span> <span class="keyword">implements</span> <span class="title">PolledConfigurationSource</span> </span>&#123;</div><div class="line"></div><div class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> Logger LOGGER = LoggerFactory.getLogger(ConsulConfigurationSource.class);</div><div class="line">    <span class="keyword">private</span> ConsulInfo consulInfo;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConsulConfigurationSource</span><span class="params">(ConsulInfo consulInfo)</span> </span>&#123;</div><div class="line">        <span class="keyword">this</span>.consulInfo = consulInfo;</div><div class="line">    &#125;</div><div class="line"></div><div class="line"><span class="comment">/**</span></div><div class="line">*动态拉去配置，默认60s拉一次</div><div class="line">*/</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> PollResult <span class="title">poll</span><span class="params">(<span class="keyword">boolean</span> initial, Object checkPoint)</span> <span class="keyword">throws</span> Exception </span>&#123;</div><div class="line">        String str = <span class="keyword">null</span>;</div><div class="line">        <span class="keyword">try</span> &#123;</div><div class="line">            Consul consul = Consul.builder().build();</div><div class="line">            KeyValueClient kvClient = consul.keyValueClient();</div><div class="line">            str = kvClient.getValueAsString(consulInfo.getKeyName()).get();</div><div class="line">        &#125; <span class="keyword">catch</span> (Throwable e) &#123;</div><div class="line">            LOGGER.error(<span class="string">"get property from consul error"</span>, e);</div><div class="line">        &#125;</div><div class="line">        Map&lt;String, Object&gt; map = <span class="keyword">new</span> HashMap&lt;&gt;();</div><div class="line">        <span class="keyword">if</span> (TextUtils.isBlank(str)) &#123;</div><div class="line">            <span class="keyword">return</span> PollResult.createFull(map);</div><div class="line">        &#125; <span class="keyword">else</span> &#123;</div><div class="line">            Properties properties = <span class="keyword">new</span> Properties();</div><div class="line">            properties.load(<span class="keyword">new</span> StringReader(str));</div><div class="line">            <span class="keyword">for</span> (Map.Entry&lt;Object, Object&gt; entry : properties.entrySet()) &#123;</div><div class="line">                map.put(entry.getKey().toString(), entry.getValue());</div><div class="line">            &#125;</div><div class="line"></div><div class="line">            <span class="keyword">return</span> PollResult.createFull(map);</div><div class="line">        &#125;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> com.config.center.consul;</div><div class="line"></div><div class="line"><span class="keyword">import</span> com.netflix.config.ConfigurationManager;</div><div class="line"><span class="keyword">import</span> com.netflix.config.DynamicConfiguration;</div><div class="line"><span class="keyword">import</span> com.netflix.config.FixedDelayPollingScheduler;</div><div class="line"><span class="keyword">import</span> org.springframework.core.env.MapPropertySource;</div><div class="line"></div><div class="line"><span class="keyword">import</span> java.util.HashMap;</div><div class="line"></div><div class="line"><span class="comment">/**</span></div><div class="line"> * ConsulPropertySource</div><div class="line"> *</div><div class="line"> * <span class="doctag">@author</span> qwf</div><div class="line"> * <span class="doctag">@version</span> 2015-08-17</div><div class="line"> */</div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConsulPropertySource</span> <span class="keyword">extends</span> <span class="title">MapPropertySource</span> </span>&#123;</div><div class="line">    <span class="keyword">private</span> DynamicConfiguration configuration;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConsulPropertySource</span><span class="params">(String name, ConsulInfo consulInfo)</span> </span>&#123;</div><div class="line">        <span class="keyword">super</span>(name, <span class="keyword">new</span> HashMap&lt;String, Object&gt;());</div><div class="line"></div><div class="line">        FixedDelayPollingScheduler scheduler = <span class="keyword">new</span> FixedDelayPollingScheduler();</div><div class="line">        scheduler.setIgnoreDeletesFromSource(<span class="keyword">true</span>);</div><div class="line">        DynamicConfiguration configuration = <span class="keyword">new</span> DynamicConfiguration(</div><div class="line">                <span class="keyword">new</span> ConsulConfigurationSource(consulInfo), scheduler);</div><div class="line">        ConfigurationManager.install(configuration);</div><div class="line">        <span class="keyword">this</span>.configuration = configuration;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">getProperty</span><span class="params">(String name)</span> </span>&#123;</div><div class="line">        <span class="keyword">return</span> configuration.getProperty(name);</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> com.config.center.consul;</div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">import</span> com.orbitz.consul.KeyValueClient;</div><div class="line"><span class="keyword">import</span> consul.Consul;</div><div class="line"><span class="keyword">import</span> consul.KeyValue;</div><div class="line"></div><div class="line"><span class="comment">/**</span></div><div class="line"> * ConsulInfo</div><div class="line"> *</div><div class="line"> * <span class="doctag">@author</span> qwf</div><div class="line"> * <span class="doctag">@version</span> 2015-08-17</div><div class="line"> */</div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConsulInfo</span> </span>&#123;</div><div class="line">    <span class="keyword">private</span> String keyName;</div><div class="line">    <span class="keyword">private</span> KeyValue keyValue;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConsulInfo</span><span class="params">(String keyName, KeyValue keyValue)</span> </span>&#123;</div><div class="line">        <span class="keyword">this</span>.keyName = keyName;</div><div class="line">        <span class="keyword">this</span>.keyValue = keyValue;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getKeyName</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">return</span> keyName;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setKeyName</span><span class="params">(String keyName)</span> </span>&#123;</div><div class="line">        <span class="keyword">this</span>.keyName = keyName;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> KeyValue <span class="title">getKeyValue</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">return</span> keyValue;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setKeyValue</span><span class="params">(KeyValue keyValue)</span> </span>&#123;</div><div class="line">        <span class="keyword">this</span>.keyValue = keyValue;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>配置如上即可，代码比较简单。<br>需要注意的是启动时保整本地的consul agent连接到集群server，以及指定一个consul tag，如果tag为“local”，那就不从consul读配置</p>
<p>运行后即可看到动态配置的效果。</p>
<hr>
<h3 id="4-ACL配置"><a href="#4-ACL配置" class="headerlink" title="4.ACL配置"></a>4.ACL配置</h3><p>ACL即为“Access Control List”，用来给consul做一些权限控制的（一定程度上弥补了没有登录校验的场景）</p>
<p>网上ACL的教程比较少，基本就是介绍下ACL是什么，官方也没有给出具体配置，只是讲了各个属性的作用<br>推荐<strong><a href="http://www.tuicool.com/articles/2InMV36" target="_blank" rel="external">http://www.tuicool.com/articles/2InMV36</a></strong>这篇文章讲的还可以，不过精华是里面引用的那篇日文文章。</p>
<p>那直接进入主题</p>
<p>consul的acl配置<br>经过老夫的对文档的查阅以及多次测试，得出的结论：<br>1.启动consul的all模式时，配置文件：</p>
<p>{<br>  “acl_datacenter”: “datacenter-tag”,<br>  “acl_master_token”: “xxxxxxxxxx”,   //这个token就是上面的种子token用来生成其余token<br>  “acl_default_policy”: “deny” //开启acl<br>}<br>这三个是必要的base属性。</p>
<ul>
<li><p>acl_default_policy：不配置rule规则的情况下对于默认行为的处理（可配置为allow，deny）<br>  对于这个，解释一下consul的白名单与黑名单<br>  当acl_default_policy为deny是，默认的api（写）行为都会被阻止，我们可以配置其子项，让比如配置key可写，这样在全部deny的情况下，出现了一个默认可写的行为，这就是白名单<br>  黑名单反之，当acl_default_policy为allow时，默认行为都是允许的，我们可以配置子项使它某些行为为deny，这就是黑名单的概念<br>若要开启all，acl_default_policy需要设置成deny</p>
</li>
<li><p>acl_master_token：这个是自己指定的，随便来一串字符串就可以了</p>
</li>
<li><p>acl_datacenter：all作用的数据中心</p>
</li>
</ul>
<p>这样配置就完成了初始工作，在启动consul节点时需要加入该配置 -config-dir [配置文件的路径/或者配置文件的父目录]</p>
<p>此时我们访问consul的web ui时，（如果不设置token的情况）是作为陌生人的模式访问的，默认情况（不设置白名单），我们只能看到services，node里的内容，key/value是屏蔽的(无法读写)，acl没有权限</p>
<p>2.创建子token</p>
<p>我们不能一直用最高权限的master token吧<br>curl -H “X-Consul-Token: secret” -X PUT -d ‘{“Name”: “dc1”, “Type”: “management”}’ <a href="http://192.168.15.19:8500/v1/acl/create?token=xxxxxxxx" target="_blank" rel="external">http://192.168.15.19:8500/v1/acl/create?token=xxxxxxxx</a></p>
<p>Name：token的name<br>Type：token的类型，有client跟management<br>token：我们上面说到的master token</p>
<p>会返回类似{“ID”:”54776fd0-510a-875b-8e50-83e8cda3f5d6”}</p>
<p>这个ID就是我们需要的子token</p>
<p>在配置中加入这个token，即可拥有相关的权限，需要注意的是，token不要加错，加错了会很麻烦，比如403forbidden，而且这个是浏览器清缓存有没用的东西，老夫暂时还没搞清楚要咋整（似乎把浏览器的缓存清理掉就能行）。</p>
<p>在说另一种acl方式，这种方式更为直接，如果token不对直接连web ui都访问不了，而且特点是屏蔽的陌生人token</p>
<p>我觉得这种方式是有缺陷的，因为官方并没有类似的说明，而且我个人也认为本身acl就不应该连web ui都控制掉<br>这种方式下，我们启动acl，此时是无法访问web ui的，因为陌生人模式被“关闭了”，我们需要在此时生成一个子token，然后节点重启，进入非acl模式，此时的配置中加入该token，然后在重启节点，进入acl模式<br>经测验，这种方式的acl_config.json与上面的不一样<br>{<br>  “acl_datacenter”: “datacenter-tag”,<br>  “acl_master_token”: “xxxxxxxxxx”,   //这个token就是上面的种子token用来生成其余token<br>  “acl_token”: “b9exxxxx-xxxx-xxxx-xxx-xxxxxxxxxx291ba”,//通过种子token生成的token<br>  “acl_default_policy”: “deny” //开启acl<br>}<br>上面只需要3个变量，这种方式4个都需要<br>不过acl_token 似乎是随意的</p>
<p>设置了token的情况<br><img src="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/ac.jpg" alt="acl"></p>
<p>不设置token的情况<br><img src="http://bifong-manhua-img.oss-cn-qingdao.aliyuncs.com/local/403.jpg" alt="403"></p>
<hr>
<h3 id="5-小结"><a href="#5-小结" class="headerlink" title="5.小结"></a>5.小结</h3><p>说了这么多，最后做个总结。<br>1.server节点在推出重启后 peers.json会被置null（该文件一般在/tmp/consul下，启动时指定的目录），原本应该是类似 [“192.168.37.42:8300”, “192.168.37.111:8300”,”192.168.37.246:8300”] 这样的json数据（server节点数据），这种情况下在重新启动server节点后会出现No cluster leader这样的错误，consul info 查看节点信息，会发现所有的server节点都是follower，无法选举出leader<br><strong>解决方案</strong>：将[“120.27.37.42:8300”, “121.42.185.111:8300”,”115.28.154.246:8300”]信息回复到peers.json中，再重新启动节点（-rejoin）</p>
<p>2.web ui的访问，如果不能访问，可以查看下启动时是否加了-client 0.0.0.0 -ui 的启动命令。因为高版本的consul似乎在默认情况下，不允许web ui的远程访问（可能是我哪里配置有问题吧），不过加了-client 0.0.0.0 -ui，所有机器都能访问到web ui界面，剩下的就是有没有权限的问题了。</p>
<hr>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/consul/" rel="tag">#consul</a>
          
            <a href="/tags/spring-boot/" rel="tag">#spring boot</a>
          
        </div>
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
          </div>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2016/08/28/ZeroMQ/" rel="prev" title="从源码分析ZeroMQ">
                从源码分析ZeroMQ <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          
  <div class="comments" id="comments">
    
      <div class="ds-thread" data-thread-key="2016/08/28/consul-config/"
           data-title="consul 配置---K/V存储及ACL" data-url="http://yoursite.com/2016/08/28/consul-config/">
      </div>
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel ">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/uploads/touxiang.jpg"
               alt="钱伟峰" />
          <p class="site-author-name" itemprop="name">钱伟峰</p>
          <p class="site-description motion-element" itemprop="description">每天进步一点点</p>
        </div>
        <nav class="site-state motion-element">
          <div class="site-state-item site-state-posts">
            <a href="/archives">
              <span class="site-state-item-count">21</span>
              <span class="site-state-item-name">日志</span>
            </a>
          </div>

          
            <div class="site-state-item site-state-categories">
              <a href="/categories">
                <span class="site-state-item-count">7</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            <div class="site-state-item site-state-tags">
              <a href="/tags">
                <span class="site-state-item-count">11</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
        </div>

        
        

        
        

      </section>

      
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">
            
              
            
            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-Consul简介"><span class="nav-number">1.</span> <span class="nav-text">1.Consul简介</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-1-consul的作用"><span class="nav-number">1.1.</span> <span class="nav-text">1.1 consul的作用</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#1-2-consul的基本架构"><span class="nav-number">1.2.</span> <span class="nav-text">1.2 consul的基本架构</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-安装及运行"><span class="nav-number">2.</span> <span class="nav-text">2.安装及运行</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#安装"><span class="nav-number">2.1.</span> <span class="nav-text">安装</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#启动"><span class="nav-number">2.2.</span> <span class="nav-text">启动</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-K-V存储"><span class="nav-number">3.</span> <span class="nav-text">3.K/V存储</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-Java案例（基于Spring-boot）"><span class="nav-number">4.</span> <span class="nav-text">4.Java案例（基于Spring boot）</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#1-maven依赖"><span class="nav-number">4.1.</span> <span class="nav-text">1.maven依赖</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-ACL配置"><span class="nav-number">5.</span> <span class="nav-text">4.ACL配置</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-小结"><span class="nav-number">6.</span> <span class="nav-text">5.小结</span></a></li></ol></div>
            
          </div>
        </section>
      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2017</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">钱伟峰</span>
</div>

<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next">
    NexT.Muse
  </a>
</div>

        

        
      </div>
    </footer>

    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
    </div>
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  



  
  <script type="text/javascript" src="/vendors/jquery/index.js?v=2.1.3"></script>

  
  <script type="text/javascript" src="/vendors/fastclick/lib/fastclick.min.js?v=1.0.6"></script>

  
  <script type="text/javascript" src="/vendors/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/velocity/velocity.ui.min.js?v=1.2.1"></script>

  
  <script type="text/javascript" src="/vendors/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.0.1"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.0.1"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.0.1"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.0.1"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.0.1"></script>



  

  
    
  

  <script type="text/javascript">
    var duoshuoQuery = {short_name:"qianweifeng"};
    (function() {
      var ds = document.createElement('script');
      ds.type = 'text/javascript';ds.async = true;
      ds.id = 'duoshuo-script';
      ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
      ds.charset = 'UTF-8';
      (document.getElementsByTagName('head')[0]
      || document.getElementsByTagName('body')[0]).appendChild(ds);
    })();
  </script>

  
    
    <script src="/vendors/ua-parser-js/dist/ua-parser.min.js?v=0.7.9"></script>
    <script src="/js/src/hook-duoshuo.js"></script>
  






  
  

  

  

  

</body>
</html>
